package cn.eaay.stock.config.thread;

import cn.eaay.stock.common.domain.TaskThreadPoolInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.RejectedExecutionHandler;

/**
 * Spring线程池配置
 */
@Slf4j
@EnableAsync
@Configuration
@EnableConfigurationProperties(TaskThreadPoolInfo.class)
public class ThreadPoolTaskExecutorConfig {

    private TaskThreadPoolInfo taskThreadPoolInfo;

    public ThreadPoolTaskExecutorConfig(TaskThreadPoolInfo taskThreadPoolInfo) {
        this.taskThreadPoolInfo = taskThreadPoolInfo;
    }

    /**
     * 定义线程池任务执行器
     */
    @Bean(name = "threadPoolTaskExecutor", destroyMethod = "shutdown")
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        // 构建线程池对象
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        // 配置核心线程数
        threadPoolTaskExecutor.setCorePoolSize(taskThreadPoolInfo.getCorePoolSize());
        // 配置最大线程数
        threadPoolTaskExecutor.setMaxPoolSize(taskThreadPoolInfo.getMaxPoolSize());
        // 配置缓冲队列
        threadPoolTaskExecutor.setQueueCapacity(taskThreadPoolInfo.getQueueCapacity());
        // 配置线程的空闲时间
        threadPoolTaskExecutor.setKeepAliveSeconds(taskThreadPoolInfo.getKeepAliveSeconds());
        // 配置线程前缀
        threadPoolTaskExecutor.setThreadNamePrefix("StockThread-");
        // 配置拒绝策略
        threadPoolTaskExecutor.setRejectedExecutionHandler(rejectedExecutionHandler());
        // 参数初始化
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

    /**
     * 自定义线程拒绝策略
     */
    @Bean
    public RejectedExecutionHandler rejectedExecutionHandler() {
        RejectedExecutionHandler errorHandler = (r, executor) -> log.info("股票任务出现异常");
        return errorHandler;
    }
}
